package dao

import (
	"chat/app/model"
	"chat/utils"
	"gorm.io/gorm"
	"log"
)

// 文档：https://gorm.io/zh_CN/docs/query.html

// UserCreate Create无论什么情况都执行插入
func UserCreate(user *model.User) {
	db := utils.GetDB()
	if result := db.Model(&user).Create(&user); result.Error != nil {
		log.Printf("userCreate: %v", result.Error)
	}
	return
}

// UserCreateBatch 批量插入
func UserCreateBatch(user *[]model.User) {
	db := utils.GetDB()
	db.Model(&user).Create(&user)
	return
}

// UserGetOneNamePass 获取部分参数
// SELECT username,password FROM users WHERE xxx = xxx and xx = xx;
func UserGetOneNamePass(mobile string, status int8) (user *model.User, rowsAffected bool) {
	db := utils.GetDB()
	result := db.Model(&user).Select("id", "passwd", "salt", "avatar", "nickname", "memo", "sex").
		Where("mobile = ? and status = ?", mobile, status).Limit(1).Find(&user)
	rowsAffected = false
	if rows := result.RowsAffected; rows > 0 {
		rowsAffected = true
	}
	return
}

// UserGetById 通过主键获取
// SELECT * FROM users WHERE id = 1;
func UserGetById(id int64) (user *model.User, rowsAffected bool) {
	db := utils.GetDB()
	result := db.Model(&user).Find(&user, id)
	//db.Model(&user).Where("id = ?",id).Find(&user)
	rowsAffected = false
	if rows := result.RowsAffected; rows > 0 {
		rowsAffected = true
	}
	return
}

// UserUpdateToken 更新单个字段
// UPDATE users SET username = "lomtom" where id = 1
func UserUpdateToken(id int64, token string) {
	db := utils.GetDB()
	db.Model(&model.User{}).Where("id = ?", id).Update("token", token)
	return
}

// Transaction 匿名事务
// 可使用db.Transaction匿名方法来表明多个操作在一个事务里面，返回err将回滚，返回nil将提交事务
func Transaction() error {
	db := utils.GetDB()
	err := db.Transaction(func(tx *gorm.DB) error {
		// 在事务中执行一些 db 操作（从这里开始，您应该使用 'tx' 而不是 'db'）
		if err := tx.Create(&model.User{Mobile: "13133333333"}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		if err := tx.Delete(&model.User{}, 28).Error; err != nil {
			return err
		}
		// 返回 nil 提交事务
		return nil
	})
	if err != nil {
		return err
	}
	return nil
}

// Transaction1 手动事务
func Transaction1() error {
	db := utils.GetDB()
	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	// 在事务中执行一些 db 操作（从这里开始，您应该使用 'tx' 而不是 'db'）
	if err := tx.Create(&model.User{Mobile: "13133333333"}).Error; err != nil {
		// 回滚事务
		tx.Rollback()
		return err
	}
	if err := tx.Delete(&model.User{}, 28).Error; err != nil {
		tx.Rollback()
		return err
	}
	// 提交事务
	return tx.Commit().Error
}

// UserQueryRawDao 原生查询
func UserQueryRawDao(sql string, values ...interface{}) (user *[]model.User) {
	db := utils.GetDB()
	db.Raw(sql, values...).Scan(&user)
	return
}

func UserGetOne(where string, args ...any) (user *model.User, rowsAffected bool) {
	db := utils.GetDB()
	result := db.Model(&user).
		Select("id", "mobile", "avatar", "sex", "nickname", "status", "memo", "create_at").
		Where(where, args...).
		Limit(1).
		Find(&user)
	rowsAffected = false
	if rows := result.RowsAffected; rows > 0 {
		rowsAffected = true
	}
	return
}

// UserJoinContactList 分页查询，可以使用Limit & Offset进行分页查询
// SELECT * FROM users OFFSET 5 LIMIT 10;
func UserJoinContactList(limit int, offset int, where string, args ...any) (user *[]model.User, total int64) {
	db := utils.GetDB()
	// 自定义取每个表的字段
	//type result struct {
	//	Name  string
	//	Email string
	//}
	//db.Model(&user).
	//	Select("users.name, emails.email").
	//	Joins("left join emails on emails.user_id = users.id").
	//	Scan(&result{})

	// join 取user表数据
	db.Table("zhyu_user as user").
		Select("user.id, user.mobile, user.avatar, user.sex, user.nickname, user.memo, user.create_at").
		Joins("LEFT JOIN zhyu_contact as contact ON user.id = contact.receive_id").
		Where(where, args...).
		Limit(limit).
		Offset(offset).
		Order("user.id desc").
		Find(&user)

	db.Table("zhyu_user as user").
		Joins("LEFT JOIN zhyu_contact as contact ON user.id = contact.receive_id").
		Select("user.id").
		Where(where, args...).
		Count(&total)
	return
}
